package cn.itsource.order.service.impl;

import cn.itsource.basic.service.impl.BaseServiceImpl;
import cn.itsource.order.domain.OrderAddress;
import cn.itsource.order.domain.OrderProduct;
import cn.itsource.order.domain.OrderProductDetail;
import cn.itsource.order.mapper.OrderAddressMapper;
import cn.itsource.order.mapper.OrderProductDetailMapper;
import cn.itsource.order.mapper.OrderProductMapper;
import cn.itsource.order.service.IOrderProductService;
import cn.itsource.org.domain.Shop;
import cn.itsource.org.mapper.ShopMapper;
import cn.itsource.pay.config.AliPayUtil;
import cn.itsource.pay.domain.AlipayInfo;
import cn.itsource.pay.domain.PayBill;
import cn.itsource.pay.mapper.AlipayInfoMapper;
import cn.itsource.pay.mapper.PayBillMapper;
import cn.itsource.pay.service.IPayBillService;
import cn.itsource.pet.domain.Point;
import cn.itsource.product.domain.Product;
import cn.itsource.product.mapper.ProductMapper;
import cn.itsource.quartz.domain.QuartzJobInfo;
import cn.itsource.quartz.service.IQuertzService;
import cn.itsource.user.domain.User;
import cn.itsource.user.domain.UserAddress;
import cn.itsource.user.mapper.UserAddressMapper;
import cn.itsource.utils.AjaxResult;
import cn.itsource.utils.CodeGenerateUtils;
import cn.itsource.utils.DistanceUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.xml.crypto.Data;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class OrderProductServiceImpl extends BaseServiceImpl<OrderProduct> implements IOrderProductService {

    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserAddressMapper userAddressMapper;

    @Autowired
    private ShopMapper shopMapper;

    @Autowired
    private OrderProductMapper orderProductMapper;
    @Autowired
    private OrderProductDetailMapper orderProductDetailMapper;

    @Autowired
    private OrderAddressMapper orderAddressMapper;
    @Autowired
    private PayBillMapper payBillMapper;

    @Autowired
    private AlipayInfoMapper alipayInfoMapper;

    @Autowired
    private IQuertzService quertzService;

    /*
      map= {productId=180, addressId=1, pay=ALIPAY}
        productId:用户下单的服务id
        addressId：用户下单，上门服务的地址id  t_user_address
        pay：支付方式

        1.根据上面已有的信息 组装一个OrderProduct对象

        2.再生成快照 组装一个OrderProductDetail对象

        3.最后生成一个OrderAddress  上门服务的地址对象

        4.生成支付记录表 t_pay_bill

     */
    @Override
    @Transactional
    public AjaxResult createOrder(Map<String, String> map, HttpServletRequest request) {
        Long product_id =Long.valueOf(map.get("productId"));
        Long address_id =Long.valueOf(map.get("addressId"));
        //获取购买的产品
        Product product = productMapper.loadById(product_id);
        //获取当前的系统登录人
        String token = request.getHeader("U-TOKEN");
        User user = (User) redisTemplate.opsForValue().get(token);
        //用的上门地址
        UserAddress userAddress = userAddressMapper.loadById(address_id);
        // 1.根据上面已有的信息 组装一个OrderProduct对象
        OrderProduct orderProduct = createOrderProduct(product,user,userAddress);
        //保存的订单信息
        orderProductMapper.save(orderProduct);

        //2.再生成快照 组装一个OrderProductDetail对象
        OrderProductDetail orderProductDetail = productToOrderProductDetail(product);
        //设置关联属性
        orderProductDetail.setOrder(orderProduct);
        orderProductDetailMapper.save(orderProductDetail);
        // 3.最后生成一个OrderAddress  上门服务的地址对象
        OrderAddress orderAddress =userAddress2OrderAddress(userAddress);
        //订单的关联属性
        orderAddress.setOrder_id(orderProduct.getId());
        orderAddress.setOrderSn(orderProduct.getOrderSn());
        orderAddressMapper.save(orderAddress);
        //生成关联的支付单号
        PayBill payBill =createPayBill(orderProduct);
        payBillMapper.save(payBill);

        //--------------添加定时任务-----------------
        QuartzJobInfo info = new QuartzJobInfo();
        info.setJobName(orderProduct.getOrderSn());
        Map<String, Object> param = new HashMap<>();
        //携带参数
        param.put("orderSn", orderProduct.getOrderSn());
        info.setParams(param);
        //设置定时任务的时间参数
        info.setFireDate(orderProduct.getLastPayTime());

        quertzService.addJob(info);
        //--------------nd-----------------
        AlipayInfo alipayInfo = alipayInfoMapper.loadByShopId(27L);
        //调用支付服务进行支付
        String payResult = AliPayUtil.pay(alipayInfo,payBill);
        return AjaxResult.me().setResultObj(payResult);
    }

    @Override
    public OrderProduct loadByOrderSn(String out_trade_no) {
        return orderProductMapper.loadByOrderSn(out_trade_no);
    }

    private PayBill createPayBill(OrderProduct orderProduct) {
        PayBill payBill = new PayBill();
        BeanUtils.copyProperties(orderProduct, payBill);
        payBill.setCreateTime(new Date());
        payBill.setMoney(orderProduct.getPrice());
        //支付通道 1
        payBill.setPayChannel(1);
        payBill.setBusinessType("businesstype_product");
        payBill.setBusinessKey(orderProduct.getId());

        return  payBill;
    }

    private OrderAddress userAddress2OrderAddress(UserAddress userAddress) {
        OrderAddress orderAddress = new OrderAddress();
        //属性拷贝，原理是 根据对象的可读可写属性进行拷贝
        BeanUtils.copyProperties(userAddress, orderAddress);

        return orderAddress;
    }

    private OrderProductDetail productToOrderProductDetail(Product product) {
        OrderProductDetail detail = new OrderProductDetail();
        //属性拷贝，原理是 根据对象的可读可写属性进行拷贝
        //两个对象的里面字段名字一致就能拷贝数据
        BeanUtils.copyProperties(product,detail);

        return detail;
    }

    //1.根据上面已有的信息 组装一个OrderProduct对象
    private OrderProduct createOrderProduct(Product product,User user,UserAddress userAddress) {
        OrderProduct orderProduct = new OrderProduct();
//        private String digest;//产品描述
        orderProduct.setDigest("[服务订单]"+product.getName());
//        private Integer state;//状态
        orderProduct.setState(0);
//        private BigDecimal price;
        orderProduct.setPrice(product.getSaleprice());
//        private String orderSn;
        /*
            订单号：全数字，唯一不能重复
         */
        orderProduct.setOrderSn(CodeGenerateUtils.generateUnionPaySn());
//        private Date lastPayTime;
        //计算15分钟以后的时间戳
        Long time = System.currentTimeMillis()+1000*60*1;
        orderProduct.setLastPayTime(new Date(time));
//        private Product product;
        //下单的服务
        orderProduct.setProduct(product);
        //买家
        orderProduct.setUser(user);

        //解析用户下单位置的经纬度
        Point point = DistanceUtil.getPoint(userAddress.getFullAddress());
        //查询所有的商家
        Shop shop = DistanceUtil.getNearestShop(point, shopMapper.loadAll());
        //卖家【提供服务的商家】
        orderProduct.setShop(shop);

        return orderProduct;
    }


}
